package plat

import (
	"encoding/json"
	"errors"
	"fmt"
	"time"

	"strconv"

	"publish/app/account/model"
)

var (
	toutiao_profit = "/media_income/data/income_statement_detail/?start_date=%s&end_date=%s&pagenum=%d"
)

func init() {
	RegisterPlat("TOUTIAO", newplat_toutiao())
}

type plattoutiao struct {
}

func newplat_toutiao() Plat {
	return &plattoutiao{}
}

func NewplatToutiao() *plattoutiao {
	return &plattoutiao{}
}


func (p *plattoutiao) GetProfit(account *model.Account, start, end time.Time) ([]AccountProfit, error) {
	rets := make([]AccountProfit, 0)
	page := 1
	for {
		vals, next, err := p.get_profit_page(account, start, end, page)
		if err != nil {
			return nil, err
		}
		if len(vals) > 0 {
			rets = append(rets, vals...)
		}
		if next <= 0 {
			break
		}
		page = next
	}
	return rets, nil
}

func (p *plattoutiao) get_profit_page(account *model.Account, start, end time.Time, page int) ([]AccountProfit, int, error) {
	phttp := newtoutiao(account.GetCookie())
	v := fmt.Sprintf(toutiao_profit, start.Format("2006-01-02"), end.Format("2006-01-02"), page)
	body, err := phttp.getReq(phttp.url(v), "Referer", "https://mp.toutiao.com/profile_v2/income-overview/income", "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, -1, err
	}

	var data ToutiaoProfitResp
	if err := json.Unmarshal(body, &data); err != nil {
		return nil, -1, err
	}

	if data.Message != "success" {
		return nil, -1, errors.New("get profit return errorms = " + data.Reason)
	}

	rets := make([]AccountProfit, 0)
	for _, profit := range data.Data.Detail {
		rets = append(rets, AccountProfit{
			AccountId: account.Id,
			Profit:    profit.Total,
			Time:      time.Now().Format("2006-01-02 15:04:05"),
			Date:      profit.Day,
		})
	}
	if page >= data.Data.TotalPagenum {
		return rets, -1, nil
	}
	return rets, page + 1, nil
}

type Indexs struct {
	Datas []map[string]float64 `json:"data"`
}

func (p *plattoutiao) GetIndex(account *model.Account, start, end time.Time) ([]AccountData, error) {
	return nil, nil
}

func (p *plattoutiao) GetEveryStatistic(account *model.Account,start,end time.Time)([]EveryDayStatisttic, error){
	datas := []EveryDayStatisttic{}
	news, err := p.getStatisticNews(account, start, end)
	if err != nil {
		fmt.Println("GetStatisticNews:", err.Error())
	} else {
		datas = append(datas, news...)
	}

	return datas, err
}

type TodayStatistic struct {
	Data TodayCount `json:"data"`
}

type TodayCount struct {
	FansCount int `json:"total_subscribe_count"`
	Count int64 `json:"go_detail_count"`
}

func (p *plattoutiao)GetAllReadCount(account *model.Account) (*TodayCount,error){
	url := `https://mp.toutiao.com/statistic/profile_stat/`

	plat := newtoutiao(account.GetCookie())
	bodyBytes, err := plat.getReq(url, "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, err
	}

	todayCount := TodayStatistic{}
	err = json.Unmarshal(bodyBytes, &todayCount)
	if err != nil {
		return nil, err
	}

	return &todayCount.Data,nil
}

func (p *plattoutiao) GetStatistic(account *model.Account, start, end time.Time) ([]AccountStatisttic, error) {
	return nil,nil
}

type DataList struct {
	PlayEffectiveCount           int64  `json:"play_effective_count"`       //播放量
	CommentCount                 int64  `json:"comment_count"`              //评论量
	SurbscribeGoDetailCount      int64  `json:"surbscribe_go_detail_count"` //粉丝阅读量
	GoDetailCount                int64  `json:"go_detail_count"`            //阅读量
	RepinCount                   int64  `json:"repin_count"`                //收藏量
	Date                         string `json:"date"`
	ShareCount                   int64  `json:"share_count"`                     // 转发量
	ImpressionCount              int64  `json:"impression_count"`                //推荐量
	SurbscribePlayEffectiveCount int64  `json:"surbscribe_play_effective_count"` //粉丝播放量
}

type Data struct {
	Pagenum      int        `json:"pagenum"`
	EndDate      string     `json:"end_date"`
	TotalNum     int        `json:"total_num"`
	TotalPagenum int        `json:"total_pagenum"`
	DataList     []DataList `json:"data_list"`
	StartDate    string     `json:"start_date"`
}

type Statistic struct {
	Data Data `json:"data"`
}

func (p *plattoutiao) getStatisticNews(account *model.Account, start, end time.Time) ([]EveryDayStatisttic, error) {
	rets := make([]EveryDayStatisttic, 0)
	page := 1
	for {
		vals, next, err := p.getStatisticNewsPage(account, start, end, page)
		if err != nil {
			return nil, err
		}
		if len(vals) > 0 {
			rets = append(rets, vals...)
		}
		if next <= 0 {
			break
		}
		page = next
	}
	return rets, nil
}

func (p *plattoutiao) getStatisticNewsPage(account *model.Account, start, end time.Time, page int) ([]EveryDayStatisttic, int, error) {

	url := fmt.Sprintf(`https://mp.toutiao.com/statistic/content_daily_stat/?start_date=%s&end_date=%s&pagenum=%d`, start.Format("2006-01-02"), end.Format("2006-01-02"), page)

	plat := newtoutiao(account.GetCookie())
	bodyBytes, err := plat.getReq(url, "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, -1, err
	}

	statistic := Statistic{}
	err = json.Unmarshal(bodyBytes, &statistic)
	if err != nil {
		return nil, -1, err
	}
	datas := []EveryDayStatisttic{}
	for _, data := range statistic.Data.DataList {
		datas = append(datas, EveryDayStatisttic{
			Date:data.Date,
			RecommentCount:data.ImpressionCount,
			ReadCount:data.GoDetailCount,
			CommentCount:data.CommentCount,
			SaveCount:data.RepinCount,
		})
	}
	if page >= statistic.Data.TotalPagenum {
		return datas, -1, nil
	}
	return datas, page + 1, nil
}

func nextWeekday(t time.Time) time.Time {
	return t.Add(time.Duration(7-t.Weekday()) * 24 * time.Hour)
}

func lastWeekday(t time.Time) time.Time {
	return t.Add(-time.Duration(t.Weekday()) * 24 * time.Hour)
}

func lastMon(t time.Time) time.Time {
	return t.Add(-time.Duration(t.Weekday()-1) * 24 * time.Hour)
}

type Detail struct {
	PlayCount int64  `json:"play_count"`
	Day       string `json:"day"`
}

type StatisticVideoData struct {
	TotalNum     int      `json:"total_num"`
	Detail       []Detail `json:"detail"`
	TotalPagenum int      `json:"total_pagenum"`
}

type StatisticVideo struct {
	Message string             `json:"message"`
	Now     int                `json:"now"`
	Data    StatisticVideoData `json:"data"`
	Reason  string             `json:"reason"`
}

func (p *plattoutiao) getStatisticVideo(account *model.Account, start, end time.Time) ([]AccountStatisttic, error) {
	rets := make([]AccountStatisttic, 0)
	page := 1
	for {
		vals, next, err := p.getStatisticVideoPage(account, start, end, page)
		if err != nil {
			return nil, err
		}
		if len(vals) > 0 {
			rets = append(rets, vals...)
		}
		if next <= 0 {
			break
		}
		page = next
	}
	return rets, nil
}

func (p *plattoutiao) getStatisticVideoPage(account *model.Account, start, end time.Time, page int) ([]AccountStatisttic, int, error) {
	url := fmt.Sprintf(`https://mp.toutiao.com/media_income/data/income_statement_detail/?start_date=%s&end_date=%s&pagenum=1`, start.Format("2006-01-02"), end.Format("2006-01-02"))

	plat := newtoutiao(account.GetCookie())
	bodyBytes, err := plat.getReq(url, "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, -1, err
	}
	statistic := StatisticVideo{}
	err = json.Unmarshal(bodyBytes, &statistic)
	if err != nil {
		return nil, -1, err
	}
	datas := []AccountStatisttic{}
	for _, data := range statistic.Data.Detail {
		datas = append(datas, AccountStatisttic{
			AccountId: account.Id,
			Num:       data.PlayCount, //播放量
			Type:      "reads_video",
			Time:      time.Now().Format("2006-01-02 15:04:05"),
			Date:      data.Day,
		})
	}

	if page >= statistic.Data.TotalPagenum {
		return datas, -1, nil
	}
	return datas, page + 1, nil
}

func (p *plattoutiao) GetLevel(account *model.Account) (string, error) {
	url := `https://mp.toutiao.com/account_info/?output=json`
	plat := newtoutiao(account.GetCookie())
	bodyBytes, err := plat.getReq(url, "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return "", err
	}
	level := Level{}
	err = json.Unmarshal(bodyBytes, &level)
	if err != nil {
		return "", err
	}
	if level.Level == "新手" {
		return LEVEL_NEW, err
	}

	if level.Level == "正常" {
		return LEVEL_MONEY, err
	}

	return "", nil
}

//https://mp.toutiao.com/media_income/data/income_statement_detail/?start_date=2017-11-09&end_date=2017-11-15&pagenum=1

func (p *plattoutiao) GetArticles(account *model.Account, start time.Time, end time.Time) ([]Article, error) {
	articles := []Article{}
	from_time := ""
	item_id := ""
	for {
		api := fmt.Sprintf(`https://mp.toutiao.com/core/article/media_article_list/?count=10&source_type=0&status=all&from_time=%s&item_id=%s`, from_time, item_id)
		plat := newtoutiao(account.GetCookie())
		bodyBytes, err := plat.getReq(api, "X-Requested-With", "XMLHttpRequest")
		if err != nil {
			return nil, err
		}

		datas := ToutiaoList{}
		if err := json.Unmarshal(bodyBytes, &datas); err != nil {
			return nil, err
		}

		if len(datas.Data.Articles) == 0 {
			return articles, nil
		}

		from_time = strconv.FormatInt(datas.Data.LastTime, 10)
		item_id = datas.Data.Articles[len(datas.Data.Articles)-1].ItemId

		for _, data := range datas.Data.Articles {
			statusMsg := ""
			status := 0

			if data.Status == 3 {
				status = 1
			}

			isReCommend := false
			if data.WasRecommended == 1 {
				isReCommend = true
			}

			t := time.Unix(data.CreateTime, 0)

			if t.Before(start) && !data.IsTopArticle {
				return articles, nil
			}

			if t.Before(end) {
				if data.IsTopArticle && t.Before(start) {
					continue
				}
				articles = append(articles, Article{
					ArticleId:   data.ItemId,
					Title:       data.Title,
					Url:         data.Url,
					Time:        t,
					Status:      status,
					FailMsg:     statusMsg,
					IsRecommend: isReCommend,

					RecommentCount : data.ImpressionCount,
					ReadCount: data.ReadCount,
					CommentCount: data.CommentCount,
					FavCount: data.FavoriteCount,
				})
			}
		}
	}
	return articles, nil
}

func (p *plattoutiao) GetPayRecord(account *model.Account, start time.Time, end time.Time) ([]PayRecord, error) {
	return nil, nil
}
func (p *plattoutiao) GetFinancialInformation(account *model.Account) (*FinancialInformation, error) {
	api := `https://mp.toutiao.com/media_income/data/bank_info/`
	plat := newtoutiao(account.GetCookie())
	bodyBytes, err := plat.getReq(api, "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, err
	}
	datas := ToutiaoPayRecord{}
	if err := json.Unmarshal(bodyBytes, &datas); err != nil {
		return nil, err
	}

	financialInformation := &FinancialInformation{}
	financialInformation.BankName = datas.Data.BankName
	financialInformation.SubBank = datas.Data.SubBankName
	financialInformation.BankAccountNumber = datas.Data.BankCardNumber
	financialInformation.BankAccountName = datas.Data.PayName
	financialInformation.Locaiton = datas.Data.Location

	return financialInformation, nil
}
